/*
    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

*/

#ifndef RASTERIZER_H
#define RASTERIZER_H

#include <QVector>
#include <QColor>

class QPainter;

namespace scene{
    class Camera;
    class SceneManager;
    class Shape;
};

namespace object{
    class Vertex;
    class Plane;
};

namespace draw{
 
class FloatMatrix;
  
class Rasterizer
{
  public:
    Rasterizer(int w, int h, scene::SceneManager *sceneMgr);
    ~Rasterizer();
    
    void setBoundaries(QVector<object::Plane*>* temp);
    float getZBuffer(int yPix, int xPix);
    void setZBuffer(int yPix, int xPix, float Z);
                          
    void calculateCanonicalBox();
    void calculateViewMatrix();
    void calculatePerspectiveMatrix();
    object::Vertex * calculateVertex(object::Vertex * val);
    
    void setupPlane(object::Plane * plane);
    void prepareLoop();
    void loopPixels(QPainter *p);
    
  private:
    QVector<QVector<float>*> m_zBuffer;
    int m_width;
    int m_height;

    float m_maxZ;

    float m_minZ;
    
    scene::SceneManager * m_sceneMgr;
    scene::Camera *m_cam;
    
    FloatMatrix *m_canonical;
    FloatMatrix *m_viewMatrix;
    FloatMatrix *m_perspective;
    FloatMatrix *m_final;
    
    // vector values
    float v0_x;
    float v0_y;
    float v0_z;
    float v0_h;
    
    float v1_x;
    float v1_y;
    float v1_z;
    float v1_h;

    float v2_x;
    float v2_y;
    float v2_z;
    float v2_h;
    
    // keep originals for lightcalculating
    object::Vertex * v0_org;
    object::Vertex * v1_org;
    object::Vertex * v2_org;
    
    // minimum x and y values to check
    float xMin;
    float xMax;

    float yMin;
    float yMax;
    
    // barycentrical helpvalues
    float fGamma;                
    float fBeta;                
    float fAlpha;               
    float f01_MIN1;                 
    float f20_MIN1;                
    float f12_MIN1;
    
    object::Plane * m_curPlane;
    
    QColor m_drawColor;
    
};

};

#endif // RASTERIZER_H
